﻿#include "opt.h"
#include"x86.h"
#include"risc.h"
#include<iostream>
#include<vector>

std::fstream pageTable,pageTable_opt;
std::vector<std::pair<uint64_t, uint8_t>> addresses;

#define TYPE 0

int main()
{
	pageTable.open("bin/page.bin", std::ios::binary | std::ios::in);
	if (!pageTable)
	{
		std::cerr << "please check if page.bin is valid.\n";
		return -2;
	}
    pageTable_opt.open("bin/page_opt.bin", std::ios::binary | std::ios::in);
	if (!pageTable_opt)
	{
		std::cerr << "please check if page_opt.bin is valid.\n";
		return -2;
	}
	std::ifstream addr("bin/address.bin");
	if (!addr)
	{
		std::cerr << "please check if address.bin is valid.\n";
		return -3;
	}
	for (int i = 0;!addr.eof();i += 16)
	{
		addr.seekg(i);
		std::pair<uint64_t, uint8_t>temp;
		addr.read(reinterpret_cast<char*>(&temp.first), sizeof(uint64_t));
		addr.read(reinterpret_cast<char*>(&temp.second), sizeof(uint8_t));
        if (temp.second!=0)
			addresses.push_back(temp);
	}
	if (TYPE == 0)
	{
		TLB_x86 old_tlb;
		TLB_OPT_x86 new_tlb;
		old_tlb.init(0);
		new_tlb.init(0, 0x10000);
		old_tlb.p.total_count = new_tlb.p.total_count = addresses.size();
		std::thread t1([&old_tlb]
			{
				while (true)old_tlb.tick();
			});
		std::thread t2([&new_tlb]
			{
				while (true)new_tlb.tick();
			});
		t1.detach();
		t2.detach();
		for (auto& i : addresses)
        {
            old_tlb.setup(i.first, i.second);
			new_tlb.setup(i.first, i.second);
        }
		std::cout << "x86 without opt:\n" << old_tlb.p << std::endl;
		std::cout << "x86 with opt:\n" << new_tlb.p << std::endl;
	}
	else if (TYPE == 1) {}
	else
	{
		std::cout << "check your code.\n";
		return -4;
	}
	return 0;
}